package top.healthylife.gateway.platform.fh.api.util;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import top.healthylife.basics.utils.exception.BusinessException;
import top.healthylife.basics.utils.utils.SystemThreadLocal;
import top.healthylife.gateway.core.util.SystemConfigUtils;
import top.healthylife.gateway.dto.request.req.ApiReqDto;
import top.healthylife.gateway.platform.fh.api.config.SystemConfig;
import top.healthylife.gateway.platform.fh.dto.unify.req.FhReqDetailsQueryUnifyDto;
import top.heathylife.gateway.common.cons.SystemCons;
import top.heathylife.gateway.common.po.RecordRequestInfo;

import java.util.Map;


/**
 * @author : GaoZeXi
 * @date 2021/11/1 11:58
 */
@Slf4j
public class FhHttpUtil {

    public static final String URL_TYPE_ONE = "https://api.fahaicc.com/vip/{}?authCode={}&rt={}&sign={}&args={}";
    public static final String URL_TYPE_TWO = "https://api.fahaicc.com/vip/{}?authCode={}&rt={}&sign={}&id={}";

    private static final String CODE = "code";
    private static final String SUCCESS = "s";
    private static final String ERROR = "e";
    private static final String MSG = "msg";

    /**
     * 请求接口
     *
     * @param apiReqDto      入参
     * @param suffixedDomain 接口后缀
     * @return T 出参对象
     */
    @SneakyThrows
    public static JSONObject HttpRequest(ApiReqDto apiReqDto, String suffixedDomain) {
        //获取账号配置信息
        SystemConfig systemConfig = systemConfigInfo(apiReqDto);
        String authCode = systemConfig.getAuthCode();
        //请求时间戳
        String rt = String.valueOf(System.currentTimeMillis());
        String sign = getSign(authCode, rt);
        //处理请求地址
        String finallyUrl;
        //分两类接口
        //非详情查询
        if (!(apiReqDto instanceof FhReqDetailsQueryUnifyDto)) {
            // 企业查询/关联方查询
            Map<String, Object> argsMap = BeanUtil.beanToMap(apiReqDto);
            String argsJson = JSONObject.toJSONString(argsMap);
            finallyUrl = getFinallyUrl(URL_TYPE_ONE, suffixedDomain, authCode, rt, sign, argsJson);
        } else {
            Map<String, Object> argsMap = BeanUtil.beanToMap(apiReqDto);
            String id = String.valueOf(argsMap.get("id"));
            if (ObjectUtil.isEmpty(id)) {
                throw new BusinessException("缺失关键参数:id");
            }
            finallyUrl = getFinallyUrl(URL_TYPE_TWO, suffixedDomain, authCode, rt, sign, id);
        }


        //默认请求方法
        JSONObject jsonObject;
        try {
            //记录请求信息
            RecordRequestInfo.recordRequest(finallyUrl, null, null, "get");
            String body = HttpUtil.createGet(finallyUrl).execute().body();
            //将三方元数据存储到线程变量
            SystemThreadLocal.set(SystemCons.ORIGIN_DATA, JSONObject.toJSONString(body));
            jsonObject = JSONObject.parseObject(body);
        } catch (Exception e) {
            if(e instanceof IORuntimeException){
                throw new BusinessException("接口请求超时,请检查网络");
            }
            throw new BusinessException("接口请求异常:{}", e.getMessage());
        }
        if (jsonObject == null) {
            return null;
        }
        if (ERROR.equalsIgnoreCase(jsonObject.getString(CODE))) {
            throw new BusinessException("接口响应异常:{}", jsonObject.getString(MSG));
        }
        if (SUCCESS.equalsIgnoreCase(jsonObject.getString(CODE))) {
            return jsonObject;
        }
        return null;
    }

    /**
     * 拼接请求地址
     *
     * @param urlTemplate    url模板
     * @param suffixedDomain 接口路径后缀
     * @param authCode       授权码
     * @param rt             时间戳
     * @param sign           签名
     * @param args           参数
     * @return 地址
     */
    public static String getFinallyUrl(String urlTemplate, String suffixedDomain, String authCode, String rt, String sign, String args) {
        String url = StrUtil.format(urlTemplate, suffixedDomain, authCode, rt, sign, args);
        log.info("请求参数:{}", args);
        log.info("最终的请求地址是:{}", url);
        return url;
    }


    //获取签名
    public static String getSign(String authCode, String time) {
        String signKey = authCode + time;
        return MD5(signKey);
    }

    public static String MD5(String source) {
        if (StringUtils.isEmpty(source)) {
            return "";
        }
        return DigestUtils.md5Hex(source);
    }

    /**
     * 访问日志输出和配置获取
     *
     * @param apiReqDto 入参
     * @return 账号信息
     */
    public static SystemConfig systemConfigInfo(ApiReqDto apiReqDto) {
        //可直接通过工具类获取这个对象
        SystemConfig o = (SystemConfig) SystemConfigUtils.get();
        log.info("请求参数为:{}", JSONObject.toJSONString(apiReqDto));
        log.info("账号信息为:{}", JSONObject.toJSONString(o));
        return o;
    }

}
